"""
欢迎来到NumPy入门学习！

NumPy (Numerical Python) 是Python科学计算的核心库。它提供了一个强大的N维数组对象，以及用于处理这些数组的函数。
几乎所有的数据科学和机器学习库，如Pandas, Scikit-learn, TensorFlow等，都构建在NumPy之上。

为什么使用NumPy?
- 性能：NumPy数组在内存中是连续存储的，并且许多底层操作是用C语言实现的，因此计算速度远快于Python的原生列表。
- 功能：提供了大量的数学函数来操作数组。
- 便捷：语法简洁，可以对整个数组进行操作，而无需编写循环。

让我们开始吧！

首先，你需要确保已经安装了NumPy。如果没有，可以在终端运行:
pip install numpy
"""

# 1. 导入NumPy库 (通常简写为np)
import numpy as np

# 2. 创建NumPy数组
print("--- 2. 创建NumPy数组 ---")
# 从Python列表创建
my_list = [1, 2, 3, 4, 5]
np_array_from_list = np.array(my_list)
print(f"从列表创建的数组: {np_array_from_list}")
print(f"数组的类型: {type(np_array_from_list)}")

# 创建一个二维数组 (矩阵)
my_2d_list = [[1, 2, 3], [4, 5, 6]]
np_2d_array = np.array(my_2d_list)
print("创建的二维数组:")
print(np_2d_array)


# 3. 数组的属性
print("\n--- 3. 数组的属性 ---")
print(f"数组的维度 (ndim): {np_2d_array.ndim}")
print(f"数组的形状 (shape): {np_2d_array.shape}") # (行数, 列数)
print(f"数组的元素总数 (size): {np_2d_array.size}")
print(f"数组元素的数据类型 (dtype): {np_2d_array.dtype}")


# 4. 创建特殊数组
print("\n--- 4. 创建特殊数组 ---")
# 创建一个所有元素都为0的数组
zeros_array = np.zeros((2, 4)) # 2行4列
print("全0数组:")
print(zeros_array)

# 创建一个所有元素都为1的数组
ones_array = np.ones((3, 3)) # 3行3列
print("全1数组:")
print(ones_array)

# 创建一个指定范围的数组 (类似Python的range)
range_array = np.arange(10, 20, 2) # 从10开始，到20结束(不含)，步长为2
print(f"范围数组: {range_array}")


# 5. 数组的数学运算 (矢量化操作)
print("\n--- 5. 数组的数学运算 ---")
arr1 = np.array([1, 2, 3, 4])
arr2 = np.array([10, 20, 30, 40])

# 数组加法
add_result = arr1 + arr2
print(f"arr1 + arr2 = {add_result}")

# 数组与标量(单个数字)的运算
scalar_mul_result = arr1 * 5
print(f"arr1 * 5 = {scalar_mul_result}")

# 也可以进行更复杂的数学运算
sqrt_result = np.sqrt(arr1)
print(f"arr1的平方根: {sqrt_result}")


# 6. 数组的索引和切片
print("\n--- 6. 数组的索引和切片 ---")
data = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])
print("原始数据:")
print(data)

# 获取单个元素 (第2行, 第3列的元素，索引从0开始)
element = data[1, 2]
print(f"\n第2行第3列的元素是: {element}")

# 切片：获取一个子数组 (前2行，从第2列到结尾)
# :2 表示从开始到索引2(不含)， 1: 表示从索引1到结尾
sub_array = data[:2, 1:]
print("\n前2行，从第2列到结尾的子数组:")
print(sub_array)


# --- 动手练习 ---
print("\n--- 动手练习 ---")
# 任务: 假设你有一组成绩数据 `grades`
grades = np.array([88, 92, 75, 68, 95, 84, 78])

# 1. 计算所有成绩的平均分 (提示: 使用 np.mean() 函数)

# 2. 找出最高分 (提示: 使用 np.max() 函数)

# 3. 给所有成绩都加上5分作为奖励 (这被称为“curve”)

# 4. 筛选出所有及格的成绩 (大于等于75分)


# --- 练习答案 (尝试自己完成后再取消下面的注释来核对) ---
# mean_grade = np.mean(grades)
# print(f"平均分: {mean_grade}")

# max_grade = np.max(grades)
# print(f"最高分: {max_grade}")

# curved_grades = grades + 5
# print(f"加5分后的成绩: {curved_grades}")

# passing_grades = grades[grades >= 75]
# print(f"及格的成绩: {passing_grades}")
